/*
尽可能还原 Promise 中的每一个 API, 并通过注释的方式描述思路和原理.
*/
// 首先它是一个构造函数
class Mypromise {
    constructor(executor){
        this.state = 'pending' //等待中
        this.sucessVal = undefined //成功的返回值
        this.rejectVal = undefined //失败的返回值
        this.onSucessCallBack = [] //成功之后回调  用于promise执行异步时候，会先执行then，但这时异步没有执行完成，不应立即执行then的里面的回调方法 参数
        this.onRejectCallBack = []  //失败之后回调

        executor(this.resolve, this.reject) //执行器，new Promise() 参数是函数，且会立即执行
    }
    //把状态修改成成功
    resolve = (val) =>{
        if(this.state == 'pending') {  //阻止状态更改后，不允许再次更改
            this.state = 'fullFilled'
            this.sucessVal = val
            if(this.onSucessCallBack.length>0){
                // 如果异步依次执行回调函数
                this.onSucessCallBack.forEach(item=>{
                    item(val)
                })
            }
        }
    }
    //把状态修改成失败
    reject = (val) =>{
        if(this.state == 'pending') {
            this.state = 'rejected'
            this.rejectVal = val
            if(this.onRejectCallBack.length>0){
                this.onRejectCallBack.forEach(item=>{
                    item(val)
                })
            }
        }
    }
    // 这个构造函数的实例上，有个then方法，then方法有两个参数，一个是成功的回调，一个失败的回调
    then(onSucess,onReject){
        let p2 = new Mypromise((resolve,reject)=>{
            // 如果当状态为fulfuilled时候，执行onSucess，并且传入成功的返回值
            // console.log(this.state, '******88')  // this.state为 fullFilled
            if(this.state == 'fullFilled'){ 
              let x = onSucess(this.sucessVal)
              resolvePromise(x, resolve, reject)
            }
            if(this.state == 'rejected'){
                let x = onReject(this.rejectVal)
                resolvePromise(x, resolve, reject)
            }
            if(this.state == 'pending'){
                this.onSucessCallBack.push(onSucess)
                this.onRejectCallBack.push(onReject)
            }
        })
        return p2
    }
    // callback无论成功失败，都会调用
    finally(callback){
        return this.then(res=>{
            return Mypromise.resolve(callback()).then(()=>value)
            // callback()
            // return res
        },err=>{
            return Mypromise.resolve(callback()).then(()=> {throw err})
        })
    }
    static all(arr){
        let array = []
        //如果有异步操作，会还没等当前传入的异步执行完，就直接resolve了，
        //因此声明一个index = 0;
        let index = 0 
        return new Mypromise((resolve,reject)=>{
            function add (key, val){
                array[key] = val
                index++
                if(index === arr.length){
                    resolve(array)
                }
            }  
            for(let i =0; i<arr.length;i++){
                let current = arr[i]
                //判断all里面的参数是否是promise对象
                //如果是普通值直接返回。如果不是先用then处理后得到值，再返回
                if(current instanceof Mypromise){
                    current.then(res => add(i,res))
                }else{
                    add(i,arr[i])
                }
            }
        })
    }
    static resolve (val){
        
       if(val instanceof Mypromise){
            return val
       } else {
            return new Mypromise((resolve,reject) =>resolve(val))  
       }
       
    }
}
function resolvePromise(x, resolve, reject){
    if(x instanceof Mypromise){
        x.then(val =>{
            resolve(val)
        },err =>{
            reject(err)
        })
    }else{
        resolve(x)
    }
}
let p1 = new Mypromise((resolve,reject) =>{
    // setTimeout(() => {
    //     resolve('成功')
    // }, 1000);
    reject('失败') 
})
// p1.then((res)=>{
//     console.log(res,'--')
//     return new Mypromise((resolve,reject)=>{
//         resolve('onthe')
//     })
// }).then((res)=>{
//     console.log(res,'--111')
// })

function aa (){
    return new Mypromise((resolve,reject)=>{
        setTimeout(() => {
            resolve('aa')
        }, 1000);
    })
}
function bb(){
    return new Mypromise((resolve,reject)=>{
        reject('失败')
    })
}
// Mypromise.all(['a','b', aa(), bb(),'cc']).then(res=>{
//     console.log(res,'all方法')
// })
Mypromise.resolve('张三').then(res=>{
    console.log(res,'resolve')
})
bb().finally(()=>{
    console.log('finally')
}).then(res =>{
    console.log('finally之后的then')
},err=>{ 

})
